home *** CD-ROM | disk | FTP | other *** search
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <math.h>
- #include <memory.h>
- #include <signal.h>
- #include <values.h>
-
- #include "messages.h"
- #include "creation.h"
- #include "game.h"
-
- typedef struct sockaddr *cliaddr;
-
- typedef struct
- {
- char Mesg[MESSAGE_BUF];
- int FromWho;
- } MemoMesg;
-
-
- Parameters s_params={30, 100, 10, 10, 12, 3, 2, 10, 10, 5, 2, 1, 2, 1, 1, 2, 4};
-
- int Queue[MAX_QUEUES]; /* nombre d'attentes dans chaque queue */
- int GoodForPlay[MAX_QUEUES]; /* nombre de joueurs souhaite pour chaque queue */
- cliaddr Clients[MAX_QUEUES][MAX_USERS];
- int Sockets[MAX_QUEUES][MAX_USERS];
- char Names[MAX_QUEUES][MAX_USERS][NAME_BUF];
- int V[MAX_QUEUES][MAX_USERS];
- char Emails[MAX_QUEUES][MAX_USERS][EMAILENGTH];
-
- #define MAX_MOTD_LINES 30 /* Message of the day */
- static char Motd[MAX_MOTD_LINES][MESSAGE_BUF];
- static int nb_motd_lines;
-
- int DeathCptr, FirstDead;
-
- int ReadMotdFile()
- {
- FILE *File;
- char buf[MESSAGE_BUF];
- int n;
-
- File=fopen(".motd", "r");
- for (n=0; n<MAX_MOTD_LINES && fgets(Motd[n], MESSAGE_BUF, File)!=NULL; n++)
- Motd[n][strlen(Motd[n])-1]='\0';
- fclose(File);
- return n;
- }
-
- void SendMotd(int sockfd)
- {
- int i;
- char buf[MESSAGE_BUF];
-
- PutInt(buf, nb_motd_lines);
- write(sockfd, buf, ENTIER_BUF);
-
- for (i=0; i<nb_motd_lines; i++)
- write(sockfd, Motd[i], MESSAGE_BUF);
- }
-
- void SendQueueValues(int sockfd)
- {
- char buf[ENTIER_BUF];
- int i;
-
- PutInt(buf, MAX_QUEUES);
- write(sockfd, buf, ENTIER_BUF);
-
- for (i=0; i<MAX_QUEUES; i++)
- {
- PutInt(buf, Queue[i]);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, GoodForPlay[i]);
- write(sockfd, buf, ENTIER_BUF);
- }
- }
-
-
- void ReadDefaultFile(Parameters *params)
- {
- FILE *File;
- char buf[100];
- int n;
-
- File=fopen(".server_defaults", "r");
- while (fscanf(File, "%s %d\n", buf, &n)>0)
- {
- if (!strcmp(buf, "SIZE_X"))
- params->SIZE_X=n;
- else if (!strcmp(buf, "SIZE_Z"))
- params->SIZE_Z=n;
- else if (!strcmp(buf, "COST_FORTRESS"))
- params->COST_FORTRESS=n;
- else if (!strcmp(buf, "COST_ARMIE"))
- params->COST_ARMIE=n;
- else if (!strcmp(buf, "COST_HOVERCRAFT"))
- params->COST_HOVERCRAFT=n;
- else if (!strcmp(buf, "COST_INVISIBILITY"))
- params->COST_INVISIBILITY=n;
- else if (!strcmp(buf, "COST_TELEPORT"))
- params->COST_TELEPORT=n;
- else if (!strcmp(buf, "DEF_FORTRESS"))
- params->DEF_FORTRESS=n;
- else if (!strcmp(buf, "DEF_ARMIE"))
- params->DEF_ARMIE=n;
- else if (!strcmp(buf, "DEF_HOVERCRAFT"))
- params->DEF_HOVERCRAFT=n;
- else if (!strcmp(buf, "ATT_ARMIE"))
- params->ATT_ARMIE=n;
- else if (!strcmp(buf, "ATT_HOVERCRAFT"))
- params->ATT_HOVERCRAFT=n;
- else if (!strcmp(buf, "MOV_ARMIE"))
- params->MOV_ARMIE=n;
- else if (!strcmp(buf, "MOV_HOVERCRAFT"))
- params->MOV_HOVERCRAFT=n;
- else if (!strcmp(buf, "TELEPORT_FIELD"))
- params->TELEPORT_FIELD=n;
- else if (!strcmp(buf, "TIME"))
- params->TIME=n;
- else if (!strcmp(buf, "CREDITS_100"))
- params->CREDITS_100=n;
- }
- fclose(File);
- }
-
-
- void SendUniverseParameters(int sockfd, Parameters *params)
- {
- char buf[ENTIER_BUF];
-
- PutInt(buf, params->TIME);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->CREDITS_100);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->SIZE_X);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->SIZE_Z);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->COST_FORTRESS);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->COST_ARMIE);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->COST_HOVERCRAFT);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->COST_INVISIBILITY);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->COST_TELEPORT);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->DEF_FORTRESS);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->DEF_ARMIE);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->DEF_HOVERCRAFT);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->ATT_ARMIE);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->ATT_HOVERCRAFT);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->MOV_ARMIE);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->MOV_HOVERCRAFT);
- write(sockfd, buf, ENTIER_BUF);
- PutInt(buf, params->TELEPORT_FIELD);
- write(sockfd, buf, ENTIER_BUF);
- }
-
-
- void SendTimer(int sockfd, int sablier)
- {
- char buf[SABLIER_BUF];
-
- SendEntete(sockfd, SABLIER);
- PutInt(buf, sablier);
- write(sockfd, buf, SABLIER_BUF);
- }
-
-
- void EnvoiCasesPrises(int sockfd, Univers *U)
- {
- Univers U2;
- int i, j, k;
-
- /* Pour ne pas envoyer trop d'informations au client */
- CreateUniverse(&U2, U->NbPlateaux, U->P[0].Taille);
- CopyUniverse(&U2, U);
- for (i=0; i<U2.NbPlateaux; i++)
- for (j=0; j<U2.P[i].Taille; j++)
- for (k=0; k<U2.P[i].Taille; k++)
- if (U2.P[i].Case[j][k].Type >= 0)
- {
- U2.P[i].Case[j][k].Type=(CASE_OCCUPEE); /* seule la couleur est envoyee au client. */
- U2.P[i].Case[j][k].Couleur=(CASE_OCCUPEE);
- }
- SendUniverse(sockfd, &U2);
- }
-
-
- void AffecteSabliers(int nbplayers, int Sabliers[MAX_USERS])
- {
- int i, chaque;
-
- if (nbplayers*s_params.TIME > MAX_TOT_TIME)
- chaque=MAX_TOT_TIME/nbplayers;
- else
- chaque=s_params.TIME;
-
- for (i=0; i<nbplayers; i++)
- Sabliers[i]=chaque;
- }
-
-
- void MovePiece(Univers *U, Case Depart, Case Arrivee)
- {
- int p=Depart.p, x=Depart.x, y=Depart.y;
-
- if (IsNear(U, Depart, Arrivee, U->P[p].Case[x][y].Type, &s_params))
- {
- U->P[Arrivee.p].Case[Arrivee.x][Arrivee.y].Couleur=U->P[p].Case[x][y].Couleur;
- U->P[Arrivee.p].Case[Arrivee.x][Arrivee.y].Type=U->P[p].Case[x][y].Type;
- U->P[Arrivee.p].Case[Arrivee.x][Arrivee.y].Caract=U->P[p].Case[x][y].Caract;
- U->P[p].Case[x][y].Couleur=CASE_VIDE;
- U->P[p].Case[x][y].Type=CASE_VIDE;
- U->P[p].Case[x][y].Caract=NORMAL;
- }
- }
-
- int GetRandomNumber(int Max)
- {
- int i, m2;
-
- m2=Max*2;
- i=random();
- while (i>m2)
- i=i/2;
- return i-Max;
- }
-
-
- void SaveName(char *Name, char *Password, int V)
- {
- FILE *File;
- int LineSize=NAME_BUF+PASSLENGTH+szi+2, i=0;
- char *Line, *Line2, buf[szi];
-
- Line=malloc(LineSize);
- Line2=malloc(LineSize);
- PutInt(buf, V);
-
- File=fopen(".players", "r+");
-
- while (fread(Line2, LineSize, 1, File) && strncmp(Name, Line2, NAME_BUF))
- i++;
- memcpy(Line, Name, NAME_BUF);
- if (Password==NULL)
- memcpy(Line+NAME_BUF, Line2+NAME_BUF, PASSLENGTH);
- else
- memcpy(Line+NAME_BUF, Password, PASSLENGTH);
- memcpy(Line+NAME_BUF+PASSLENGTH, buf, szi);
- Line[LineSize-1]='\n';
- rewind(File);
- fseek(File, i*LineSize, 0);
- fwrite(Line, LineSize, 1, File);
-
- fclose(File);
- }
-
- void InformeJoueurs(int joueur, int *Socket, char *Message, int ErrorType, int nbplayers,
- char PNames[MAX_USERS][NAME_BUF])
- {
- int i, j;
- char msg[10];
-
- for (i=0; i<nbplayers; i++)
- if (i!=joueur && Socket[i]>=0)
- {
- SendMessage(Socket[i], Message, -1);
- PutInt(msg, ErrorType);
- PutInt(msg+szi, joueur);
- SendMessage(Socket[i], msg, -1);
- }
- }
-
- void RegisterDead(int dead, int nbplayers, int *V)
- {
- V[dead]-=(nbplayers-DeathCptr);
- V[dead]=(V[dead]<0?0:V[dead]);
- if (!DeathCptr)
- FirstDead=dead;
- DeathCptr++;
- }
-
- int AttackPiece(Univers *U, OneMovement Move, int movenumber, int joueur, int Socket[MAX_USERS],
- int nbplayers, char PNames[MAX_USERS][NAME_BUF], int *V)
- {
- int i, j, Montot=0, Sontot=0, MemoEnnemy, MemoType, MemoCaract;
- Case c, memo, amove;
-
- for (i=0; i<Move.nbcases; i++)
- {
- c=Move.cases[i];
- if (IsWhom(U, c.p, c.x, c.y, joueur)==ENNEMY)
- {
- memo=c;
- i=Move.nbcases; /* on sort de la boucle */
- }
- }
- MemoEnnemy=U->P[c.p].Case[c.x][c.y].Couleur;
- MemoType=U->P[c.p].Case[c.x][c.y].Type;
- MemoCaract=U->P[c.p].Case[c.x][c.y].Caract;
-
- for (i=0; i<Move.nbcases; i++)
- {
- c=Move.cases[i];
- if (IsWhom(U, c.p, c.x, c.y, joueur)==MYARMIE &&
- IsNear(U, c, memo, U->P[c.p].Case[c.x][c.y].Type, &s_params))
- {
- amove=c;
- switch(U->P[c.p].Case[c.x][c.y].Type)
- {
- case ARMEE:
- Montot+=s_params.ATT_ARMIE;
- break;
- case HOVERCRAFT:
- Montot+=s_params.ATT_HOVERCRAFT;
- break;
- }
- }
- }
-
- if (Montot==0)
- return 0;
-
- if (U->P[memo.p].Case[memo.x][memo.y].Caract==INVISIBLE)
- {
- if (U->P[memo.p].Case[memo.x][memo.y].Type!=FORTERESSE)
- {
- MovePiece(U, amove, memo); /* piece invisible "ecrasee" */
- return 1;
- }
- else
- return 0; /* on n'ecrase pas une forteresse invisible ! */
- }
-
- Sontot=DefenseTotal(U, memo.p, memo.x, memo.y, &s_params);
- if (Montot>Sontot)
- {
- char message[100], *detail;
- int Chance, Dp, Dx, Dy, Sort;
-
- Chance=GetRandomNumber(100);
- if (Chance<40) /* ------ 40% de chances d'eliminer la piece */
- {
- U->P[memo.p].Case[memo.x][memo.y].Couleur=CASE_VIDE;
- U->P[memo.p].Case[memo.x][memo.y].Type=CASE_VIDE;
- U->P[memo.p].Case[memo.x][memo.y].Caract=NORMAL;
- Sort=0;
- }
- else if (Chance<70) /* 30% de chances de la faire basculer de camps */
- {
- if (MemoCaract!=CHEF)
- U->P[memo.p].Case[memo.x][memo.y].Couleur=joueur;
- Sort=1;
- }
- else /* ----- 30% de chances de la randoteleporter... */
- {
- Dp=GetRandomNumber(U->NbPlateaux-1);
- Dx=GetRandomNumber(U->P[0].Taille-1);
- Dy=GetRandomNumber(U->P[0].Taille-1);
- if (IsWhom(U, Dp, Dx, Dy, joueur)!=CASE_VIDE)
- { /* --------- piece supprimee ----------- */
- U->P[memo.p].Case[memo.x][memo.y].Couleur=CASE_VIDE;
- U->P[memo.p].Case[memo.x][memo.y].Type=CASE_VIDE;
- U->P[memo.p].Case[memo.x][memo.y].Caract=NORMAL;
- Sort=0;
- }
- else
- { /* ---------- piece teleportee ------------ */
- U->P[Dp].Case[Dx][Dy].Couleur=U->P[memo.p].Case[memo.x][memo.y].Couleur;
- U->P[Dp].Case[Dx][Dy].Type=U->P[memo.p].Case[memo.x][memo.y].Type;
- U->P[Dp].Case[Dx][Dy].Caract=U->P[memo.p].Case[memo.x][memo.y].Caract;
- U->P[memo.p].Case[memo.x][memo.y].Couleur=CASE_VIDE;
- U->P[memo.p].Case[memo.x][memo.y].Type=CASE_VIDE;
- U->P[memo.p].Case[memo.x][memo.y].Caract=NORMAL;
- Sort=2;
- }
- }
- if (Sort==0)
- detail="Unit destroyed";
- else if (Sort==1)
- detail="Unit switched owner";
- else
- detail="Unit randoteleported";
-
- sprintf(message, "Attack Movement No %d Successful (%s)", movenumber, detail);
- SendMessage(Socket[joueur], message, -1);
- sprintf(message, "Attack From %d On [%d %d %d] : Defense Failed (%s)",
- joueur, memo.p, memo.x, memo.y, detail);
- SendMessage(Socket[MemoEnnemy], message, -1);
-
- if ((Sort==0 || Sort==1) && MemoCaract==CHEF)
- {
- char Message[MESSAGE_BUF];
- SendMessage(Socket[MemoEnnemy], "You have been kilLed... R.I.P :-)", -1);
- SendEntete(Socket[MemoEnnemy], DEBLOCK);
- close(Socket[MemoEnnemy]);
- Socket[MemoEnnemy]=(-1);
- RegisterDead(MemoEnnemy, nbplayers, V);
- ChangeToPlayer(U, MemoEnnemy, joueur);
- sprintf(Message, "Player (%d)%s has been killed by (%d)%s",
- MemoEnnemy, PNames[MemoEnnemy], joueur, PNames[joueur]);
- InformeJoueurs(MemoEnnemy, Socket, Message, KILLED, nbplayers, PNames);
- }
- return 1;
- }
- else
- {
- char message[100];
- sprintf(message, "Attack Movement No %d Failed", movenumber);
- SendMessage(Socket[joueur], message, -1);
- sprintf(message, "Attack From %d On [%d %d %d] : Defense Successful",
- joueur, memo.p, memo.x, memo.y);
- SendMessage(Socket[MemoEnnemy], message, -1);
- return 0;
- }
- }
-
-
-
- void ChangeUniverse(Univers *U, OneMovement *Moves, int joueur, int Socket[MAX_USERS],
- int nbplayers, char PNames[MAX_USERS][NAME_BUF], int *V)
- {
- int i, j, myarmies=0, ennemies=0, vides=0;
-
- /* ------ verification que chaque case est utilisee une seule fois -------- */
- for (i=0; i<NB_MOVES; i++)
- for (j=0; j<Moves[i].nbcases; j++)
- if (!IsUnique(Moves, i, j+1, Moves[i].cases[j].p, Moves[i].cases[j].x, Moves[i].cases[j].y))
- {
- SendMessage(Socket[joueur], "Bad Movement", -1);
- return;
- }
-
- for (i=0; i<NB_MOVES; i++)
- if (Moves[i].nbcases)
- {
- myarmies=0; ennemies=0; vides=0;
- for (j=0; j<Moves[i].nbcases; j++)
- {
- Case c=Moves[i].cases[j];
- int r=IsWhom(U, c.p, c.x, c.y, joueur);
- if (r==CASE_VIDE)
- vides++;
- else if (r==MYARMIE)
- myarmies++;
- else if (r==ENNEMY)
- ennemies++;
- else
- StopError(5678);
- }
- if (vides==1 && myarmies==1 && ennemies==0) /* --------- Deplacement -------------- */
- {
- if (IsWhom(U, Moves[i].cases[0].p, Moves[i].cases[0].x, Moves[i].cases[0].y, joueur)
- == CASE_VIDE)
- MovePiece(U, Moves[i].cases[1], Moves[i].cases[0]);
- else
- MovePiece(U, Moves[i].cases[0], Moves[i].cases[1]);
- }
- else if (vides==0 && myarmies>0 && ennemies==1) /* ------------- Attaque -------------- */
- AttackPiece(U, Moves[i], i, joueur, Socket, nbplayers, PNames, V);
- else
- {
- char message[40];
- sprintf(message, "Bad movement"); /* bad movement no (i+1) */
- SendMessage(Socket[joueur], message, -1);
- }
- }
- }
-
-
- void BadDataProcedure(int joueur, char PNames[MAX_USERS][NAME_BUF],
- int *Socket, int *V, int nbplayers)
- {
- char Message[MESSAGE_BUF];
-
- SendMessage(Socket[joueur], "** Bad data... ciao !!", -1);
- close(Socket[joueur]);
- Socket[joueur]=(-1);
- RegisterDead(joueur, nbplayers, V);
- sprintf(Message, "Connection error with player (%d)%s", joueur, PNames[joueur]);
- InformeJoueurs(joueur, Socket, Message, DATAERROR, nbplayers, PNames);
- }
-
-
- void TraiteMessage(Univers *U, char *Message, int Socket[MAX_USERS],
- int ForWho, int FromWho, int nbplayers, char PNames[MAX_USERS][NAME_BUF],
- int *NbAlive, int *OKForNul, int *V)
- {
- char mesg[MESSAGE_BUF];
- int i, r;
-
- if (ForWho==-1) /* message pour le serveur */
- if (!strcmp(Message, "QUIT"))
- {
- SendEntete(Socket[FromWho], DEBLOCK);
- close(Socket[FromWho]);
- Socket[FromWho]=(-1);
- RegisterDead(FromWho, nbplayers, V);
- sprintf(mesg, "Player (%d)%s Gives Up", FromWho, PNames[FromWho]);
- InformeJoueurs(FromWho, Socket, mesg, ABANDON, nbplayers, PNames);
- ErasePlayer(U, FromWho);
- (*NbAlive)--;
- }
- else if (!strcmp(Message, "NUL"))
- {
- sprintf(mesg, "Player (%d)%s propose nul game", FromWho, PNames[FromWho]);
- InformeJoueurs(FromWho, Socket, mesg, NOT_A_DEATH, nbplayers, PNames);
- OKForNul[FromWho]=1;
- for (r=1, i=0; i<nbplayers; i++)
- if (!OKForNul[i])
- r=0;
- if (r) /* si tous les joueurs ont demande match nul... MATCH NUL */
- {
- sprintf(mesg, "** NUL GAME -- Nobody wins **");
- for (i=0; i<nbplayers; i++)
- if (Socket[i]>=0) {
- SendMessage(Socket[i], mesg, -1);
- SendEntete(Socket[i], DEBLOCK);
- close(Socket[i]); }
- exit(0); /* ---------- THE END (match nul) ---- Les scores ne sont pas sauvegardes */
- }
- }
- else if (!strcmp(Message, "WAR"))
- {
- sprintf(mesg, "Player (%d)%s cancels any previous nul game proposition",
- FromWho, PNames[FromWho]);
- InformeJoueurs(FromWho, Socket, mesg, NOT_A_DEATH, nbplayers, PNames);
- OKForNul[FromWho]=0;
- }
- else
- Message[MESSAGE_BUF-1]='\0';
-
- else if (ForWho==-2) {
- for (i=0; i<nbplayers; i++)
- if (Socket[i]>0 && i!=FromWho)
- SendMessage(Socket[i], Message, (FromWho+1)*100); }
- else if (ForWho>=nbplayers || ForWho<0 || Socket[ForWho]<0 || !IsVoisin(U, FromWho, ForWho))
- SendMessage(Socket[FromWho], "Can't reach this player", -1);
- else
- SendMessage(Socket[ForWho], Message, FromWho);
- }
-
-
- void TesteVictoire(int nbplayers, int Socket[MAX_USERS], char PNames[MAX_USERS][NAME_BUF],
- int V[MAX_USERS])
- {
- int cpt=0, i, j;
-
- for (i=0; i<nbplayers; i++)
- if (Socket[i]>=0)
- cpt++;
-
- if (!cpt)
- exit(0);
-
- if (cpt==1) /* ------- il ne reste plus qu'un joueur ------- */
- {
- for (i=0; i<nbplayers && Socket[i]<0; i++);
- SendMessage(Socket[i], "You win !", -1);
- SendEntete(Socket[i], DEBLOCK);
- close(Socket[i]);
-
- V[i]+=nbplayers; /* le gagnant ... */
- if (nbplayers>3)
- V[FirstDead]=0; /* le premier mort d'un match a plus de trois joueurs est resete' */
-
- for (i=0; i<nbplayers; i++) /* sauvegarde des points */
- SaveName(PNames[i], NULL, V[i]);
-
- exit(0); /* ------------- THE END --------------- */
- }
- }
-
-
- void BeginTheGameServer(int NBPLX, cliaddr Client[MAX_USERS], int Socket[MAX_USERS],
- int nbplayers, char PNames[MAX_USERS][NAME_BUF], int V[MAX_USERS],
- char Email[MAX_USERS][EMAILENGTH])
- {
- char buf[QUEUE_BUF], Message[MESSAGE_BUF], Entete[ENTETE_BUF], Sabuf[SABLIER_BUF];
- int i, j, mesg, joueur, Who, CONTINUE, Resultat, Sabliers[MAX_USERS], PECULE, cpt;
- int Order[MAX_USERS], GrainM=0, GrainP=0, PlayerOK[MAX_USERS], NbAlive, OKForNul[MAX_USERS];
- Univers U, U2;
- OneMovement Moves[MAX_USERS][NB_MOVES];
-
- for (i=0; i<nbplayers; i++)
- OKForNul[i]=0;
- DeathCptr=1;
-
- srand(clock()); /* initialisation du generateur d'"aleation" */
- CreateUniverse(&U, NBPLX, s_params.SIZE_X);
- CreateUniverse(&U2, NBPLX, s_params.SIZE_X);
- AffecteSabliers(nbplayers, Sabliers);
-
- /* ----- ENVOI de la valeur du sablier (<=> "Go !") ---------------------- */
- for (i=0; i<nbplayers; i++)
- {
- PutInt(Sabuf, Sabliers[i]);
- write(Socket[i], Sabuf, SABLIER_BUF);
- }
-
- /* ----- ENVOI des noms des joueurs --------------------------------------- */
- for (i=0; i<nbplayers; i++)
- for (j=0; j<nbplayers; j++)
- write(Socket[i], PNames[j], NAME_BUF);
-
- /* ----- ENVOI des emails des joueurs --------------------------------------- */
- for (i=0; i<nbplayers; i++)
- for (j=0; j<nbplayers; j++)
- write(Socket[i], Email[j], EMAILENGTH);
-
- /* ----- ENVOI des scores des joueurs --------------------------------------- */
- for (i=0; i<nbplayers; i++)
- for (j=0; j<nbplayers; j++) {
- PutInt(buf, V[j]);
- write(Socket[i], buf, ENTIER_BUF); }
-
- PECULE=NBPLX*s_params.SIZE_X*s_params.SIZE_X/100*s_params.CREDITS_100/nbplayers;
- PutInt(buf, PECULE);
- for (i=0; i<nbplayers; i++)
- {
- PutInt(buf+szi, i); /* la position du joueur */
- write(Socket[i], buf, QUEUE_BUF);
- EnvoiCasesPrises(Socket[i], &U);
- if (WaitForThisSocket(Socket[i], 100))
- /* 5 minutes pour placer les pieces */
- {
- if (GetEntete(Socket[i])==UNIVERS)
- {
- GetUniverse(Socket[i], &U2);
- CopyUniverse(&U, &U2);
- }
- else /* ne doit pas arriver (erreur de transmission...) */
- {
- SendEntete(Socket[i], DEBLOCK);
- close(Socket[i]);
- Socket[i]=(-1);
- RegisterDead(i, nbplayers, V);
- }
- }
- else
- {
- SendEntete(Socket[i], DEBLOCK);
- close(Socket[i]);
- Socket[i]=(-1); /* joueur elimine si delai ecoule */
- RegisterDead(i, nbplayers, V);
- }
- }
-
- /* ------------------ Begining of GAME ----------------------------------- */
-
- NbAlive=0;
- for (i=0; i<nbplayers; i++)
- if (Socket[i]>=0)
- {
- Univers U2;
- CreateUniverse(&U2, NBPLX, s_params.SIZE_X);
- CopyUniverse(&U2, &U);
- TransformUniverse(&U2, i);
- SendUniverse(Socket[i], &U2);
- NbAlive++;
- }
-
- if (!NbAlive) /* plus de joueurs !! */
- exit(0);
-
- while(1)
- {
- int NBOK=0;
- TesteVictoire(nbplayers, Socket, PNames, V);
-
- for (joueur=0; joueur<nbplayers; joueur++) /* On envoie le coup de depart */
- if (Socket[joueur]!=-1)
- SendEntete(Socket[joueur], MY_TURN);
-
- for (i=0; i<nbplayers; i++)
- PlayerOK[i]=0;
-
- GrainP=0; GrainM=0;
-
- while (NBOK<NbAlive) /* ---- chaque seconde ---- */
- {
- sleep(1);
- for (joueur=0; joueur<nbplayers; joueur++) /* - pour chaque joueur - */
- {
- if (Socket[joueur]==-1)
- continue;
-
- Resultat=WaitForThisSocket(Socket[joueur], 0);
- if (Resultat)
- {
- mesg=GetEntete(Socket[joueur]);
- if (mesg==MOVEMENT)
- {
- Order[NBOK]=joueur;
- PlayerOK[joueur]=1;
- GetMovement(Socket[joueur], Moves[NBOK]);
- NBOK++;
- GrainM=NBOK;
- GrainP=NbAlive-NBOK;
- }
- else if (mesg==MESSAGE)
- {
- GetMessage(Socket[joueur], &Who, Message);
- TraiteMessage(&U, Message, Socket, Who, joueur, nbplayers, PNames,
- &NbAlive, OKForNul, V);
- }
- else /* (mesg!=MOVEMENT && mesg !=MESSAGE) */
- {
- BadDataProcedure(joueur, PNames, Socket, V, nbplayers);
- ErasePlayer(&U, joueur);
- NbAlive--;
- }
- }
- } /* --- fin pour chaque joueur ---- */
-
- for (i=0; i<nbplayers; i++) /* le sable coule... */
- {
- if (Socket[i]>0)
- {
- if (PlayerOK[i])
- Sabliers[i]+=GrainP;
- else
- {
- Sabliers[i]-=GrainM;
- if (Sabliers[i]<=0)
- {
- SendMessage(Socket[i], "Time Death... You Lose !", -1);
- SendEntete(Socket[i], DEBLOCK);
- close(Socket[i]);
- Socket[i]=(-1);
- RegisterDead(i, nbplayers, V);
- ErasePlayer(&U, i);
- NbAlive--;
- sprintf(Message, "Player (%d)%s Has Been Killed By Time", i, PNames[i]);
- InformeJoueurs(i, Socket, Message, TIMEDEATH, nbplayers, PNames);
- }
- }
- if (Socket[i]>=0)
- SendTimer(Socket[i], Sabliers[i]);
- }
- }
- } /* --- chaque seconde ---- */
-
- for (i=0; i<NBOK; i++)
- ChangeUniverse(&U, Moves[i], Order[i], Socket, nbplayers, PNames, V);
-
- NbAlive=0;
- for (i=0; i<NBOK; i++) /* ------ Le serveur envoie le nouvel univers... -------*/
- if (Socket[Order[i]]>=0)
- {
- Univers U2;
- CreateUniverse(&U2, NBPLX, s_params.SIZE_X);
- CopyUniverse(&U2, &U);
- TransformUniverse(&U2, Order[i]);
- SendUniverse(Socket[Order[i]], &U2);
- NbAlive++;
- }
- }
- }
-
-
- int LoadName(char *Name, char *Password)
- {
- FILE *File;
- int LineSize=NAME_BUF+PASSLENGTH+szi+2, IsOK=0;
- char *Line;
- int Value;
-
- Line=malloc(LineSize);
-
- File=fopen(".players", "r");
- while(!IsOK)
- {
- if (!fread(Line, 1, LineSize, File))
- IsOK=2;
- else if (!strncmp(Name, Line, NAME_BUF))
- IsOK=1;
- }
- fclose(File);
- if (IsOK==2) /* le nom n'existe pas dans le fichier */
- return 0;
- memcpy(Password, Line+NAME_BUF, PASSLENGTH);
- GetInt(Line+NAME_BUF+PASSLENGTH, &Value);
- return Value;
- }
-
- int ReceiveName(int sockfd, char *Name)
- {
- int NameOK=0, V, i;
- char Password[PASSLENGTH], buf[szi], Pass[PASSLENGTH];
-
- while (!NameOK)
- {
- if (MyRead(sockfd, Name, NAME_BUF, TIMEOUT)==-1) /* RECOIT le NOM du joueur */
- return -1;
-
- if (V=LoadName(Name, Password)) /* le nom existe */
- {
- PutInt(buf, 1234);
- write(sockfd, buf, szi);
- if (MyRead(sockfd, Pass, PASSLENGTH, TIMEOUT)==-1)
- return -1;
- if (!strncmp(Pass, Password, PASSLENGTH))
- {
- PutInt(buf, 5678); /* password OK */
- NameOK=1;
- }
- else
- PutInt(buf, 2345); /* password inexact */
- write(sockfd, buf, szi);
- }
- else /* le nom n'existe pas */
- {
- PutInt(buf, 2345);
- write(sockfd, buf, szi);
- if (MyRead(sockfd, buf, szi, TIMEOUT)==-1)
- return -1;
- GetInt(buf, &i);
- if (i==8765)
- {
- if (MyRead(sockfd, Password, PASSLENGTH, TIMEOUT)==-1)
- return -1;
- SaveName(Name, Password, 1);
- V=0; /* score de depart a la creation des joueurs */
- NameOK=1;
- }
- }
- }
- return V;
- }
-
-
- int GetWhichQueue(int sockfd, int desir, int nb_wanted, int *WhichQueue,
- char *Name, char *email, int Va)
- {
- char buf[QUEUE_BUF];
- int i, PPtr, NbInQueue=0;
-
-
- for (i=0; i<Queue[desir]; i++)
- if (Sockets[desir][i]==-1)
- {
- PPtr=i;
- i=Queue[desir]+1;
- }
-
- if (i==Queue[desir])
- {
- PPtr=Queue[desir];
- Queue[desir]++;
- }
-
- if (GoodForPlay[desir]==0)
- GoodForPlay[desir]=nb_wanted;
-
- strncpy(Names[desir][PPtr], Name, NAME_BUF); /* le NOM */
- Sockets[desir][PPtr]=sockfd; /* memorise le SOCKET du client */
- strncpy(Emails[desir][PPtr], email, EMAILENGTH);
- V[desir][PPtr]=Va;
- for (i=0; i<Queue[desir]; i++)
- if (Sockets[desir][i]>=0)
- NbInQueue++;
- PutInt(buf, GoodForPlay[desir]);
- PutInt(buf+szi, NbInQueue);
- *WhichQueue=desir;
- write(sockfd, buf, QUEUE_BUF); /* ENVOI des donnees au client */
-
- for (i=0; i<Queue[desir]; i++) /* on avertit les autres patients que l'on approche du but */
- {
- if (i!=PPtr && Sockets[desir][i]>=0)
- {
- PutInt(buf, NbInQueue);
- write(Sockets[desir][i], buf, ENTIER_BUF);
- }
- }
-
- if (NbInQueue==GoodForPlay[desir])
- return 1;
- else
- return 0;
- }
-
-
- void LoginProcedure(int accept_sockfd, int sockfd, int NBPLX)
- {
- char buf[QUEUE_BUF], email[EMAILENGTH], Name[NAME_BUF];
- int desir, nb_wanted, ZQ, Va, i;
-
- SendUniverseParameters(sockfd, &s_params);
- SendMotd(sockfd);
- SendQueueValues(sockfd);
-
- if ((Va=ReceiveName(sockfd, Name)) != -1 &&
- MyRead(sockfd, email, EMAILENGTH, TIMEOUT) != -1)
- {
- MyRead(sockfd, buf, ENTIER_BUF, TIMEOUT); /* queue... */
- GetInt(buf, &desir);
- MyRead(sockfd, buf, ENTIER_BUF, TIMEOUT); /* nb de joueurs */
- GetInt(buf, &nb_wanted);
-
- if (GetWhichQueue(sockfd, desir, nb_wanted, &ZQ, Name, email, Va))
- if (fork()==0)
- {
- close(accept_sockfd); /* child */
- BeginTheGameServer(NBPLX, Clients[ZQ], Sockets[ZQ], GoodForPlay[ZQ], Names[ZQ],
- V[ZQ],Emails[ZQ]);
- }
- else
- {
- for (i=0; i<GoodForPlay[ZQ]; i++)
- close(Sockets[ZQ][i]);
- }
-
- if (ZQ>-1 && Queue[ZQ]==GoodForPlay[ZQ])
- {
- Queue[ZQ]=0;
- GoodForPlay[ZQ]=0;
- }
- }
- }
-
-
-
- void InitQueues()
- {
- int i;
- for (i=0; i<MAX_QUEUES; i++)
- {
- Queue[i]=0;
- GoodForPlay[i]=0;
- }
- }
-
- void DisplayHelp()
- {
- printf("Usage : server -p<port>\n");
- }
-
- void main(int argc, char *argv[])
- {
- int i, PORTN=0, NBPLX=0, j=0;
-
- int sockfd, newsockfd, addrlen;
- struct sockaddr_in serv_addr, client_addr;
-
- for (i=1; i<argc; i++)
- if (!strncmp(argv[i], "-p", 2))
- PORTN=atoi(argv[i]+2);
- if (!PORTN)
- {
- DisplayHelp();
- exit(0);
- }
-
- InitQueues();
- signal(SIGHUP, SIG_IGN);
- signal(SIGPIPE, SIG_IGN);
-
- if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- {
- fprintf(stderr, "** socket error (unable to create a socket) **\n");
- exit(0);
- }
-
- bzero(&serv_addr, sizeof(serv_addr));
- serv_addr.sin_port = PORTN;
- serv_addr.sin_family = AF_INET;
-
-
- if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
- {
- fprintf(stderr, "** bind error (probably bad port number) **\n");
- exit(0);
- }
-
- if (listen(sockfd, BACK_LOG) < 0)
- {
- fprintf(stderr, "** listen error **\n");
- exit(0);
- }
-
- ReadDefaultFile(&s_params);
- nb_motd_lines=ReadMotdFile();
-
- NBPLX=s_params.SIZE_Z;
- if (NBPLX > MAX_LEVELS)
- {
- NBPLX=MAX_LEVELS;
- printf("Maximum number of levels : %d\n", MAX_LEVELS);
- }
-
- for (;;)
- {
- newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &addrlen);
- if (newsockfd < 0)
- continue;
-
- for (i=0; i<MAX_QUEUES; i++) /* reception des sorties de queue */
- for (j=0; j<Queue[i]; j++)
- if (Sockets[i][j]>=0 && WaitForThisSocket(Sockets[i][j], 0))
- {
- Sockets[i][j]=(-1);
- close(Sockets[i][j]);
- }
-
- LoginProcedure(sockfd, newsockfd, NBPLX);
-
- }
- }
-